/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Structures;

import java.awt.Frame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import net.sourceforge.javaocr.gui.meanSquareOCR.TrainingImageSpec;
import net.sourceforge.javaocr.ocrPlugins.mseOCR.CharacterRange;
import net.sourceforge.javaocr.ocrPlugins.mseOCR.OCRScanner;
import net.sourceforge.javaocr.ocrPlugins.mseOCR.TrainingImage;
import net.sourceforge.javaocr.ocrPlugins.mseOCR.TrainingImageLoader;

/**
 *
 * @author Mariusz
 */
public class ReceiptProfile implements Serializable{
    private String name;
    private ArrayList<TrainingImageSpec> images;

    public ReceiptProfile(String n) {
        name = n;
        images = new ArrayList<TrainingImageSpec>();
    }

    public String getName() {
        return name;
    }

    public void setName(String na) {
        name = na;
    }

    public ArrayList<TrainingImageSpec> getImages() {
        return images;
    }
    
    public boolean isDefault(){
        return false;
    }
    
    public boolean checkIfProduct(String p) {
        throw new UnsupportedOperationException("Profil nie jest profilem domyślnym.");
    }
    
    public Entry getProduct(String p) {
        throw new UnsupportedOperationException("Profil nie jest profilem domyślnym.");
    }
    
    // Dodajemy training image. Zwraca true, gdy sie uda i false gdy nie.
    // low, high - przedzial z tablicy ascii.
    public boolean addTrainingImage(File f, char low, char high){
        try {
            TrainingImageSpec newImage = new TrainingImageSpec();
            newImage.setFileLocation(f.getCanonicalPath());
            newImage.setCharRange(new CharacterRange(low, high));
            images.add(newImage);
            return true;
        } catch (IOException ex) {
            Logger.getLogger(ReceiptProfile.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public boolean addTrainingImage(String s, char low, char high){
        try {
            TrainingImageSpec newImage = new TrainingImageSpec();
            File file = new File(s);
            newImage.setFileLocation(file.getCanonicalPath());
            newImage.setCharRange(new CharacterRange(low, high));
            images.add(newImage);
            return true;
        } catch (IOException ex) {
            Logger.getLogger(ReceiptProfile.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public String readReceipt(String path) {
        try {
            OCRScanner ocrScanner = new OCRScanner();
            HashMap<Character, ArrayList<TrainingImage>> trainingImages = getTrainingImageHashMap(images);
            ocrScanner.addTrainingImages(trainingImages);
            BufferedImage targetImage = ImageIO.read(new File(path));
            String text = ocrScanner.scan(targetImage, 0, 0, 0, 0, null);
            return text;
        } catch (Exception ex) {
            Logger.getLogger(ReceiptProfile.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public String readReceipt(File file) {
        try {
            OCRScanner ocrScanner = new OCRScanner();
            HashMap<Character, ArrayList<TrainingImage>> trainingImages = getTrainingImageHashMap(images);
            ocrScanner.addTrainingImages(trainingImages);
            BufferedImage targetImage = ImageIO.read(file);
            String text = ocrScanner.scan(targetImage, 0, 0, 0, 0, null);
            return text;
        } catch (Exception ex) {
            Logger.getLogger(ReceiptProfile.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    private HashMap<Character, ArrayList<TrainingImage>> getTrainingImageHashMap(ArrayList<TrainingImageSpec> imgs) throws Exception {
        TrainingImageLoader loader = new TrainingImageLoader();
        HashMap<Character, ArrayList<TrainingImage>> trainingImages = new HashMap<Character, ArrayList<TrainingImage>>();
        Frame frame = new Frame();

        for (int i = 0; i < imgs.size(); i++) 
            loader.load(
                    frame,
                    imgs.get(i).getFileLocation(),
                    imgs.get(i).getCharRange(),
                    trainingImages);
        return trainingImages;
    }

    public LinkedList<String> parseString(String s) {
        LinkedList<String> products = new LinkedList<String>();

        StringTokenizer token = new StringTokenizer(s, "\n");
        while (token.hasMoreTokens())
            products.addLast(token.nextToken());
        
        return products;
    }
}
